package com.lzy.utils;

import com.lzy.annotation.AuthCheck;
import com.lzy.constant.Constants;
import com.lzy.context.LocalUser;
import com.lzy.enums.ExceptionEnums;
import com.lzy.exception.ServiceException;
import com.lzy.exception.authority.PermissionNotAllowedException;
import com.lzy.exception.user.JwtExpiredException;
import com.lzy.security.LoginUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Set;

/**
 * @author lyw
 * @Date 2023/3/6-上午11:45
 */
@Component
public class PermissionUtil {

  @Autowired
  private TokenUtil tokenUtil;

  @Autowired
  private RedisCache redisCache;

  public boolean checkPermission(AuthCheck ac) {
    String tokenKey = tokenUtil.getTokenKey(LocalUser.me().getUserId());
    String redisToken = redisCache.getCacheObject(tokenKey);
    String userKey = tokenUtil.getUserKey(LocalUser.me().getUserId(), redisToken);
    LoginUser loginUser = redisCache.getCacheObject(userKey);

    // 是否下线
    if (StringUtil.isEmpty(redisToken)) {
      throw new JwtExpiredException("会话已超时，请重新登陆！");
    }

    // ——--------————————————————————权限校验——————————————————————-----------

    if (!loginUser.getRoles().contains(Constants.ADMIN)) {
      Set<String> roles = loginUser.getRoles();
      Set<String> permissions = loginUser.getPermissions();

      if ((StringUtil.isNull(roles) || roles.size() == 0) && (StringUtil.isNull(permissions) || permissions.size() == 0)) {
        throw new ServiceException(ExceptionEnums.NO_PERMISSION_OPERATION.getCode(), ExceptionEnums.NO_PERMISSION_OPERATION.getMessage());
      }

      // 角色校验
      String role = ac.hasRole();
      if (StringUtil.isNotEmpty(role)) {
        if (!roles.contains(role)) {
          throw new PermissionNotAllowedException("您还没有权限访问");
        }
      }

      String[] anyRole = ac.hasAnyRole();
      if (StringUtil.isNotEmpty(anyRole)) {
        boolean flag = true;
        for (String needRole : roles) {
          for (String curRole : anyRole) {
            if (needRole.equals(curRole)) {
              flag = false;
            }
          }
        }

        if (flag) {
          throw new PermissionNotAllowedException("您还没有权限访问");
        }
      }

      String authority = ac.hasAuthority();
      if (StringUtil.isNotEmpty(authority)) {
        if(!permissions.contains(authority)) {
          throw new PermissionNotAllowedException("您还没有权限访问");
        }
      }

      String[] authorities = ac.hasAnyAuthority();
      if (StringUtil.isNotEmpty(anyRole)) {
        boolean flag = true;
        for (String needPermission : permissions) {
          for (String curPermission : authorities) {
            if (needPermission.equals(curPermission)) {
              flag = false;
            }
          }
        }

        if (flag) {
          throw new PermissionNotAllowedException("您还没有权限访问");
        }
      }
    }

    return true;
  }
}
